package com.example.gatewaytoken.util;

import io.jsonwebtoken.Claims;
import io.jsonwebtoken.ExpiredJwtException;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.nio.charset.StandardCharsets;
import java.util.*;

/**
 * JWT工具类
 * @author whx
 * @date 2022/4/12
 */
public class JWTUtil {

    private final static Logger log = LoggerFactory.getLogger(JWTUtil.class);

    /**
     * jwt 加解密类型
     */
    private static final SignatureAlgorithm ALGORITHM = SignatureAlgorithm.HS256;

    /**
     * jwt 生成密钥使用的密码 私钥
     */
    private static final String SECRET = "asdkasdjad";

    /**
     * jwt 添加至http head中的前缀
     */
    private static final String SEPARATOR = "Bearer ";

    /**
     * 添加到PAYLOAD的签发者
     */
    private static final String ISSUE = "55555";

    /**
     * 添加至PAYLOAD的有效期（秒）
     */
    private static final int TIMEOUT = 60*60*24;

    /**
     * 生成token
     * @param userId
     * @return
     */
    public static String generateToken(String userId){
        // 创建PAYLOAD的私有声明（要放入token中的信息）
        Map<String,Object> claims = new HashMap<>();
        claims.put("userId",userId);
        long currentTime = System.currentTimeMillis();
        return Jwts.builder()
                // 唯一id
                .setId(UUID.randomUUID().toString())
                // 签发时间
                .setIssuedAt(new Date(currentTime))
                // 签发人
                .setIssuer(ISSUE)
                // 加密算法，私钥
                .signWith(ALGORITHM,SECRET)
                // 过期时间(毫秒)
                .setExpiration(new Date(currentTime + TIMEOUT * 1000))
                .addClaims(claims)
                .compact();
    }

    /**
     * 解析token 获取key
     * @param token
     * @param key
     * @return
     */
    public static Object getVal(String token,String key){
        return getClaimsBody(token).get(key);
    }

    /**
     * token是否过期
     * @param token
     * @return
     */
    public static boolean isExpiration(String token){
        try{
            return getClaimsBody(token).getExpiration().before(new Date());
        }catch (ExpiredJwtException e){
            return true;
        }
    }

    public static Claims getClaimsBody(String token){
        return Jwts.parser().setSigningKey(SECRET).parseClaimsJws(token).getBody();
    }


}
